package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JScrollPane;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JTabbedPane;

import logic.*;

public class MainWindow extends JFrame implements MouseListener,MouseMotionListener{

	private JPanel contentPane;
	private JPanel _DebugPanel;
	private JPanel _ConfigPanel;
	private Hashtable<BoardPanel,Pestanna> _Pestannas;
	private Hashtable<JLabel,Block> 	_Tokens;
	private ArrayList<JLabel>	_Restaurables;
	private JPanel _IzqPanel;
	private JPanel _DerPanel;
	private JTabbedPane _TabPanelBoard;
	
	//eventos
	private int _MousePressedX0;
	private int _MousePressedY0;
	private int _LabelDraggedX0;
	private int _LabelDraggedY0;
	private JComponent _LabelContainer0;
	private SintaxAnalizer_ _Analizador;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainWindow frame = new MainWindow();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainWindow() {
		_Pestannas = new Hashtable<BoardPanel,Pestanna>();
		_Tokens    = new Hashtable<JLabel,Block>();
		_Restaurables = new ArrayList<JLabel>();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 673, 473);
		
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		JMenu mnNewMenu = new JMenu("New menu");
		menuBar.add(mnNewMenu);
		
		JMenuItem mntmNewMenuItem = new JMenuItem("New menu item");
		mnNewMenu.add(mntmNewMenuItem);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		
		JScrollPane scrollPane = new JScrollPane();
		
		JScrollPane scrollPane_1 = new JScrollPane();
		
		_TabPanelBoard = new JTabbedPane(JTabbedPane.TOP);
		_TabPanelBoard.addMouseListener(this);
		GroupLayout gl_contentPane = new GroupLayout(contentPane);
		gl_contentPane.setHorizontalGroup(
			gl_contentPane.createParallelGroup(Alignment.LEADING)
				.addGroup(Alignment.TRAILING, gl_contentPane.createSequentialGroup()
					.addContainerGap()
					.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(_TabPanelBoard, GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, 125, GroupLayout.PREFERRED_SIZE)
					.addContainerGap())
		);
		gl_contentPane.setVerticalGroup(
			gl_contentPane.createParallelGroup(Alignment.LEADING)
				.addGroup(Alignment.TRAILING, gl_contentPane.createSequentialGroup()
					.addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING)
						.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)
						.addComponent(scrollPane_1, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)
						.addComponent(_TabPanelBoard, GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE))
					.addContainerGap())
		);
		
		_IzqPanel = new JPanel();
		scrollPane.setViewportView(_IzqPanel);
		
		_DerPanel = new JPanel();
		scrollPane_1.setViewportView(_DerPanel);
		_DerPanel.setLayout(null);
		
		_ConfigPanel = new JPanel();
		_TabPanelBoard.addTab("Config", null, _ConfigPanel, null);
		
		_DebugPanel = new JPanel();
		_TabPanelBoard.addTab("Debug", null, _DebugPanel, null);
		
		contentPane.setLayout(gl_contentPane);
		
		inicializeTabs();
		inicializeTokens();
		inicializeVariables();
	}

	public void loadPestanna( int i ){
		
	}
	
	private void inicializeTokens(){
		_Tokens    = new Hashtable<JLabel,Block>();
		for (int i=0 ; i < Constantes.IMAGES.length ; i++){
			JLabel label = new JLabel();
			label.setIcon((Icon) new ImageIcon(Constantes.IMAGES[i]) );
			_Tokens.put( label, new Command(i,0,0) );
			_DerPanel.add(label);
			label.setBounds(20,20+i*(20+Constantes.DEFAULT_LABEL_HEIGHT),50,50);
			label.addMouseMotionListener(this);
			label.addMouseListener(this);
			
			JScrollPane currentScrollPane = (JScrollPane)_DerPanel.getParent().getParent();
			currentScrollPane.getVerticalScrollBar().setValue(currentScrollPane.getVerticalScrollBar().getMaximum());
			currentScrollPane.updateUI();
		}
	}
	
	private void inicializeVariables(){
	}
	
	private void inicializeTabs(){		
		addTab("main");
		addTab("tab1");
		addTab("tab2");
	}
	

	
	private void addTab( String pName ){
		BoardPanel board = new BoardPanel();
		board.setPreferredSize( new Dimension(1000,1000) );
		board.setVisible(true);
		
		JScrollPane scrollPanelBoard = new JScrollPane();
		scrollPanelBoard.add(board);
		scrollPanelBoard.setViewportView(board);

		_TabPanelBoard.addTab(pName, null, scrollPanelBoard, null);
		
		JLabel labelShadow = new JLabel("");
		labelShadow.setBounds(0, 0, 0, 0);
		labelShadow.setIcon(new ImageIcon("shadow.gif"));
		labelShadow.setBackground(new Color(102, 0, 153));
		labelShadow.setVisible(true);
		board.set_LabelShadow(labelShadow);		

		board.add(labelShadow);
		board.setLayout(null);
		board.addMouseListener(this);
		_Pestannas.put(board,new Pestanna());
		crearInicio(board);
	}
	
	private void crearInicio(BoardPanel board){
		JLabel bloqueInicio  = new JLabel();
		Command command = new Command( Constantes.ID_INICIO,0,0 );
		board.add( bloqueInicio );
		if (_Pestannas.get(board).get_Cuadricula().get(0) == null ){
			_Pestannas.get(board).get_Cuadricula().put(0, new Hashtable<Integer,Block>());
		}
		_Pestannas.get(board).get_Cuadricula().get(0).put(0, command);
		JLabel labelInicio = new JLabel();
		labelInicio.setIcon(new ImageIcon("GIFS/Inicio.gif"));
		labelInicio.setBounds(0,0,Constantes.DEFAULT_LABEL_WIDTH,Constantes.DEFAULT_LABEL_HEIGHT);
		board.add(labelInicio);
	}
	
	public void newVariable(){
		Random random = new Random();
		int TabsNoBoards = 2;
		int margin = 20;
		Pestanna currentTab = _Pestannas.get(_TabPanelBoard.getSelectedIndex()-TabsNoBoards);
		
		JLabel label = new JLabel();
		label.setIcon(new ImageIcon("GIFS/Varible.png"));
		label.setBounds(20,20+currentTab.get_Variables().size()*(margin+Constantes.DEFAULT_LABEL_HEIGHT),50,50);
		label.addMouseMotionListener(this);
		label.addMouseListener(this);
		label.setBackground(Color.getHSBColor(random.nextFloat() , random.nextFloat(), 0.5f));
		_DerPanel.add(label);
		_DerPanel.setPreferredSize( new Dimension(
				(int)_DerPanel.getPreferredSize().getWidth(),
				(int)_DerPanel.getPreferredSize().getHeight() + Constantes.DEFAULT_LABEL_WIDTH + margin) );
		
		JScrollPane currentScrollPane = (JScrollPane)_TabPanelBoard.getSelectedComponent();
		currentScrollPane.getVerticalScrollBar().setValue(currentScrollPane.getVerticalScrollBar().getMaximum());
		currentScrollPane.updateUI();
	}


	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		JComponent component = (JComponent)arg0.getComponent();
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent evento) {
		if (evento.getComponent().getClass().isInstance(new JLabel() ) ){
			setCursor(Cursor.HAND_CURSOR);
			JLabel label = (JLabel)evento.getComponent();
			
			_MousePressedX0 = evento.getX();
			_MousePressedY0 = evento.getY();
			
			_LabelDraggedX0 = label.getX();
			_LabelDraggedY0 = label.getY();
			_LabelContainer0 = (JComponent)label.getParent();
			getContentPane().add(label,0);
			int x = label.getX() +_TabPanelBoard.getX()+1;
			int y = label.getY() +_TabPanelBoard.getY()+1;
			label.setLocation( x , y );
			label.setVisible(false);
			System.out.println(label.getBounds().toString());
		}else if ( evento.getComponent().getClass().isInstance( new JButton() )  ){
			JButton button = (JButton)evento.getComponent();
			button.setLocation(button.getX(), button.getY()+70);
			newVariable();
		}
		
	}
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		JComponent component = (JComponent)e.getComponent();
		if (component.getClass().isInstance( new JLabel() ) && _TabPanelBoard.getSelectedIndex() >= 0 ){
			System.out.println("RELEASED");
			BoardPanel board = (BoardPanel)_TabPanelBoard.getSelectedComponent().getComponentAt(10, 10).getComponentAt(10,10);
			setCursor(Cursor.DEFAULT_CURSOR);
			JLabel label = (JLabel)component;	
			label.setVisible(true);
			board.add(label,0);
			if (/* board.getMousePosition(true) != null*/true){
				System.out.println("RELEASED");
				int row = Math.round((float)(label.getX() - _TabPanelBoard.getX() - board.getParent().getParent().getX() - board.getX() - 1)
						/(float)board.getLabelHeight());
				int col = Math.round((float)(label.getY() - _TabPanelBoard.getY() - board.getParent().getParent().getY() - board.getY() - 1)
						/(float)board.getLabelWidth());
				if ( _Analizador.addBloque(row,col , label, _Pestannas.get(0))){
					System.out.println( "true" );
					label.setLocation(row*board.getLabelHeight(),col*board.getLabelWidth());
					if (_Restaurables.contains(label)){
						System.out.println("RELEASED");
						restaurar(label);
					}
				}else{
					JLabel block = restaurar(label);
					if ( this._LabelContainer0.equals( board ) ){
						_Restaurables.remove(block);
					}
					label.getParent().remove(label);					
				}
			}else{
				JLabel block = restaurar(label);
				if ( _LabelContainer0.equals( board ) ){
					_Restaurables.remove(block);
				}
				label.getParent().remove(label);
			}
			board.get_LabelShadow().setVisible(false);
			System.out.println("RELEASED");
			this.repaint();
		}
	}
	
	public JLabel restaurar( JLabel label){
		JLabel restoredBlock = new JLabel();
		BoardPanel board = (BoardPanel)_TabPanelBoard.getSelectedComponent().getComponentAt(10, 10).getComponentAt(10,10);
		_LabelContainer0.add(restoredBlock);
		restoredBlock.setBounds(this._LabelDraggedX0, this._LabelDraggedY0,board.getLabelWidth(), board.getLabelHeight() );
		restoredBlock.setIcon(label.getIcon());
		restoredBlock.addMouseListener(this);
		restoredBlock.addMouseMotionListener(this);
		_Restaurables.add(restoredBlock);
		restoredBlock.setBackground(label.getBackground());
		_Restaurables.add(label);
		restoredBlock.repaint();
		return restoredBlock;
	}
	
	public void mouseDragged(MouseEvent e) {
		JLabel label = (JLabel)e.getComponent();
		BoardPanel board = (BoardPanel)_TabPanelBoard.getSelectedComponent().getComponentAt(10, 10).getComponentAt(10,10);
		label.setVisible(true);
		label.setLocation(
				e.getX() + label.getX() - _MousePressedX0,
				e.getY() + label.getY() - _MousePressedY0);
		System.out.println(label.getBounds().toString());
		board.get_LabelShadow().setBounds(
				Math.round((float)(label.getX() - _TabPanelBoard.getX() -board.getParent().getParent().getX() - board.getX() - 1)
						/(float)BoardPanel.getLabelHeight())*BoardPanel.getLabelHeight(),
				Math.round((float)(label.getY() - _TabPanelBoard.getY() -board.getParent().getParent().getY() - board.getY() - 1)
						/(float)BoardPanel.getLabelWidth())*BoardPanel.getLabelWidth(),
				BoardPanel.getLabelWidth(),BoardPanel.getLabelHeight()
		);
		board.get_LabelShadow().setVisible(true);
		repaint();
	}
}
